package org.unei.mp.ch7;

import java.util.concurrent.atomic.AtomicReference;

/**
 * 提供了先来先服务的公平性
 * 缺点：在无cache的NUMA系统结构下性能很差，每个线程都自旋等待其前驱节点的locked域变为false，
 * 如果内存位置较远，那么性能将会受到损失。然而在cache一致性的系统结构上，该方法非常有效。
 * 
 * @author sunlei
 *
 */
public class CLHLock implements Lock{

	AtomicReference<QNode> tail=new AtomicReference<QNode>(new QNode());
	
	ThreadLocal<QNode> myPred;
	ThreadLocal<QNode> myNode;
	
	public CLHLock(){

		myNode=new ThreadLocal<QNode>(){
			protected QNode initialValue(){
				return new QNode();
			}
		};
		
		myPred=new ThreadLocal<QNode>(){
			protected QNode initialValue(){
				return null;
			}
		};
	}
	
	@Override
	public void lock() {
		QNode qnode=myNode.get();
		qnode.locked=true;
		QNode pred=tail.getAndSet(qnode);
		myPred.set(pred);
		System.out.println(Thread.currentThread().getName()+" join...");
		while(pred.locked){
		}
	}

	@Override
	public void unlock() {
		QNode qnode=myNode.get();
		qnode.locked=false;
		myNode.set(myPred.get());
	}

	class QNode{
		public QNode(){
			id++;
		}
		
		public int id=0;
		public boolean locked;
	}
}
